<?php

require_once('Classes/Utils/FileLift/FileLiftCore.inc');


class  FileLiftProcessor extends FileLiftCore
{
	public function __construct($profile, $data)
	{	
		parent::__construct($profile, $data);
		
		//check required parameters
		if($this->checkData())
			$this->kill($this->checkData());
			
		//set working categorie	
		$this->setCat($this->data['cat']); 
			
		//actions to do
		switch($this->data['go']) {
			case 'up':
				$uploadedFile = $_FILES[$this->data['name']];
				
				//check if the file meets the requeriments
				$err = $this->checkUploadFile($uploadedFile, $this->workCat['options']);
				if($err) {
					$this->manageStatus(3, $err);	//set 'notallowed' as status
					break;
				}
				
				//rename the file
				$uploadedFile['name'] = $this->ren($uploadedFile['name'], $this->getInfo($uploadedFile['tmp_name']));
				
				//implement appropriate code if proceed
				$uploadedFile = FileLiftPreProcessor::__preProcessor($uploadedFile);
				if(  !file_exists($uploadedFile['tmp_name'])  )
					$this->kill('Preprocessor returned a file that does not exist: '.$uploadedFile['tmp_name']);
				
				//if overwrite warnings are activated, check if $this->store() will overwrite
				/*if($this->conf['overwritewarnings'] && $this->find($uploadedFile['name'], $this->conf['tmpPath'])) {
					$this->manageStatus(5);	//set 'overwrite' as status
					break;
				}*/
				
				//Store file (tmp dir), check response and set status
				$r = $this->store($uploadedFile['tmp_name'], $this->tmpPath . '/' . $uploadedFile['name']);
				$uploadedFile['name'] = $r;
				if($r) {
					$this->manageStatus(2, false, false, $this->find($r));	//set 'info' as status
					$this->setIndexEntry($uploadedFile['name'], 'stored', $this->data['cat'], $this->data['obj']);			//set new index entry
				}
				else
					$this->manageStatus(1);	//set 'nostore' as status
					
				break;
				
			case 'down':
				//search the file & check response
				$r = $this->find($this->data['file']);
				if($r)
					$this->streamFile($r);
				else
					$this->manageStatus(4);	//set 'notfound' as status
				break;
				
			case 'delete':
				//search the file & check response
				$r = $this->find($this->data['file'], $this->path);
				if($r)
				{
					if($this->del($r)) {
						$this->manageStatus(6);	//set 'deleted' as status
						$this->updateIndexEntry($this->data['file'], 'deleted');	//update index entry' status 
						break;
					}
				}
				$this->manageStatus(4);	//set 'notfound' as status
				break;
				
			case 'info':
				$r = $this->find($this->data['file']);
				
				if($r)
					$this->manageStatus(2, false, false, $r);	//set 'info' as status
				else
					$this->manageStatus(4);	//set 'notfound' as status
				break;
		}
		
		//auto response to client
		if(!$this->conf['autoresponse'])
			return;
		switch($this->data['go']) {
			case 'up':
				$this->sendJS($this->conf['responseJS'], $this->find($uploadedFile['name']));
				break;
			case 'info':
			case 'delete':
				$this->sendJSON();
				break;
		}
	}
	
	//Send the transaction result to the client 
	//(useless if you have 'autoresponse' set to true. This can be set into config array)
	public function sendResponse() {
		switch($this->data['go']) {
			case 'up':
				$this->sendJS($this->conf['responseJS'], $this->find($uploadedFile['name']));
				break;
			case 'info':
			case 'delete':
				$this->sendJSON();
				break;
		}
	}
	
	// INTERNAL METHODS
	
	/*set & get the status of the transaction
	 * @s : mode/status to be set
	 * @option : in case 'status = notallowed' sets the specific error msg from config array
	 * @nofile : in case 'status = nofile' sets the specific error msg from config array
	 * @file : in case 'status = info' it's required to return the info to the client
	 * */
	private function manageStatus($s = false, $option = false, $nofile = false, $file=false) {
		switch($s) {
			case 0:		//nofile
				$this->status = 'nofile';
				$this->errormsg = $this->conf['statusMSG']['nofile'][$nofile];
				break;
			case 1:		//stored
				$this->status = 'store';
				$this->errormsg = $this->conf['statusMSG']['nostore'];
				break;
			case 2:		//info
				$this->status = 'info';
				$this->errormsg = $this->conf['statusMSG']['info'];
				$this->errormsg = $this->replaceTags($this->errormsg, $this->getInfo($file));
				break;
			case 3:		//file does not meet the requeriments
				$this->status = 'notallowed';
				$this->errormsg = $this->conf['statusMSG']['notallowed'] . $this->workCat['errors'][$option];
				break;
			case 4:		//file expected onto server not found
				$this->status = 'notfound';
				$this->errormsg = $this->conf['statusMSG']['notfound'];
				break;
			case 5:		//user will overwrite a file yet uploaded
				$this->status = 'overwrite';
				$this->errormsg = $this->conf['statusMSG']['overwrite'];
				break;
			case 6:		//user will overwrite a file yet uploaded
				$this->status = 'deleted';
				$this->errormsg = $this->conf['statusMSG']['deleted'];
				break;
			case false:
				return $this->status;
		}
				 
		$this->errormsg = $this->replaceTags($this->errormsg);
	}
	
	// CRASH PREVENTION
	
	//Tells whether a uploaded file meets the categorie options
	//returns false if the file meets the options, true or string if not
	private function checkUploadFile($filearray, $catOptions)
	{
		if(!$filearray)
			return true;
		if(!$this->checkUploadError($filearray['error'])) {
			//set 'nofile' error
			$this->manageStatus(0, false, $filearray['error']);	
			return true;
		}
		if(!$catOptions)
			return false;
		foreach($catOptions as $option => $value)
		{
			switch($option) {
				case 'maxsize':
					if($filearray['size'] / 1024 > $value) {
						return $option;
					}
					break;
				case 'type':
					$extensions = explode(",", $value);
					$ok = false;
					foreach($extensions as $ext) {
						if(strpos($filearray['type'], $ext))
							$ok = true;
					}
					if($ok)
						break;
					return $option;
				case 'imagesize_fix':
					$image = new Imagick($filearray['tmp_name']);
					if($image->getImageWidth() != $value[0] || $image->getImageHeight() != $value[1])
						return $option;
					break;
				default:
					return 'checksetup';
			}	
		}
		return false;
	}
	
	//checks if uploaded file is ok returns: (false = ok, integer = error)
	private function checkUploadError($error) {
		switch($error)		//error messages can be set into setup array
		{
			case '1':
			case '2':
			case '3':
			case '4':
			case '6':
			case '7':
			case '8':
				break;
			default:
				return true;
		}
		return false;
	}
	
	//Checks received data
	//returns false if its ok, string otherwise
	private function checkData() {
		//check id @privatefolders=true
		if($this->conf['privatefolders'] && !$this->data['id'])
			return 'MISSED IDENTIFIER. Can\'t start privatefolders transaction';
			
		//check categorie
		if(!$this->data['cat'])
			return 'MISSED "cat" PARAMETER';
		if(!$this->cats[$this->data['cat']])
			return 'WRONG VALUE ON "cat" PARAMETER';
		
		//check go 
		if(!$this->data['go'])
			return 'MISSED "go" PARAMETER';
		switch($this->data['go'])
		{
			case 'up';
				if(!$this->data['name'])
					return 'MISSED "name" PARAMETER';
				if(!$_FILES[$this->data['name']])
					return 'FILE MISSED';
				break;
			case 'down':
			case 'delete':
			case 'info':
				if(!$this->data['file'])
					return 'MISSED "file" PARAMETER';
				break;
			default:
				die('WRONG VALUE ON "go" PARAMETER');
		}
	}
}
?>